package com.lhl.log.autoconfigure;

import com.lhl.log.annotation.Log;
import com.lhl.log.annotation.ParamLog;
import com.lhl.log.annotation.ResultLog;
import com.lhl.log.annotation.ThrowingLog;
import com.lhl.log.core.LogCallback;
import com.lhl.log.core.VoidLogCallback;
import com.lhl.log.formatter.DefaultParamFormatter;
import com.lhl.log.formatter.DefaultResultFormatter;
import com.lhl.log.formatter.ParamFormatter;
import com.lhl.log.formatter.ResultFormatter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @className: Slf4jProperties
 * @description: TODO 类描述
 * @author: king
 * @date: 2020-09-16 15:02
 **/
@ConfigurationProperties(prefix = "logging.slf4j")
public class Slf4jProperties implements InitializingBean {
    /**
     * 参数格式化
     */
    private Class<? extends ParamFormatter> globalParamFormatter = DefaultParamFormatter.class;

    /**
     * 返回结果格式化
     */
    private Class<? extends ResultFormatter> globalResultFormatter = DefaultResultFormatter.class;

    /**
     * 综合日志回调
     */
    private Class<? extends LogCallback> globalLogCallback = VoidLogCallback.class;

    /**
     * 参数日志回调
     */
    private Class<? extends LogCallback> globalParamLogCallback = VoidLogCallback.class;

    /**
     * 结果日志回调
     */
    private Class<? extends LogCallback> globalResultLogCallback = VoidLogCallback.class;

    /**
     * 异常日志回调
     */
    private Class<? extends LogCallback> globalThrowingLogCallback = VoidLogCallback.class;

    /**
     * 回调容器
     */
    private final Map<String, Class<? extends LogCallback>> callbackContainer = new ConcurrentHashMap<>(4);

    @Override
    public void afterPropertiesSet() throws Exception {
        this.callbackContainer.put(Log.class.getName(), this.globalLogCallback);
        this.callbackContainer.put(ParamLog.class.getName(), this.globalParamLogCallback);
        this.callbackContainer.put(ResultLog.class.getName(), this.globalResultLogCallback);
        this.callbackContainer.put(ThrowingLog.class.getName(), this.globalThrowingLogCallback);
    }

    public Class<? extends LogCallback> getCallback(Annotation annotation) {
        return this.callbackContainer.get(annotation.annotationType().getName());
    }

    public Class<? extends ParamFormatter> getGlobalParamFormatter() {
        return globalParamFormatter;
    }

    public void setGlobalParamFormatter(Class<? extends ParamFormatter> globalParamFormatter) {
        this.globalParamFormatter = globalParamFormatter;
    }

    public Class<? extends ResultFormatter> getGlobalResultFormatter() {
        return globalResultFormatter;
    }

    public void setGlobalResultFormatter(Class<? extends ResultFormatter> globalResultFormatter) {
        this.globalResultFormatter = globalResultFormatter;
    }

    public Class<? extends LogCallback> getGlobalLogCallback() {
        return globalLogCallback;
    }

    public void setGlobalLogCallback(Class<? extends LogCallback> globalLogCallback) {
        this.globalLogCallback = globalLogCallback;
    }

    public Class<? extends LogCallback> getGlobalParamLogCallback() {
        return globalParamLogCallback;
    }

    public void setGlobalParamLogCallback(Class<? extends LogCallback> globalParamLogCallback) {
        this.globalParamLogCallback = globalParamLogCallback;
    }

    public Class<? extends LogCallback> getGlobalResultLogCallback() {
        return globalResultLogCallback;
    }

    public void setGlobalResultLogCallback(Class<? extends LogCallback> globalResultLogCallback) {
        this.globalResultLogCallback = globalResultLogCallback;
    }

    public Class<? extends LogCallback> getGlobalThrowingLogCallback() {
        return globalThrowingLogCallback;
    }

    public void setGlobalThrowingLogCallback(Class<? extends LogCallback> globalThrowingLogCallback) {
        this.globalThrowingLogCallback = globalThrowingLogCallback;
    }
}